package com.von.nhcf.controller;

import com.von.nhcf.api.MysqlRemoteService;
import com.von.nhcf.api.RedisRemoteService;
import com.von.nhcf.config.ShortMessageProperties;
import com.von.nhcf.constant.NhcfConstant;
import com.von.nhcf.entity.po.MemberPO;
import com.von.nhcf.entity.vo.MemberLoginVO;
import com.von.nhcf.entity.vo.MemberVO;
import com.von.nhcf.util.ResultEntity;
import com.von.nhcf.util.SendSmsUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;

@Controller
public class MemberController {
    @Autowired
    RedisRemoteService redisRemoteService;
    @Autowired
    MysqlRemoteService mysqlRemoteService;
    @Autowired
    private ShortMessageProperties shortMessageProperties;

    @RequestMapping("member/auth/do/logout")
    public String doLogout(HttpSession session) {
        session.invalidate();
        return "redirect:/member/auth/to/login/page";
    }
    @RequestMapping("member/auth/do/login")
    public String doLogin(@RequestParam("loginacct") String loginacct,
                          @RequestParam("userpswd") String userpswd,
                          ModelMap modelMap,
                          HttpSession session) {
        // 判断账号或密码是否为空
        if (loginacct == "" || userpswd == "") {
            modelMap.addAttribute(NhcfConstant.ATTR_MESSAGE_NAME, NhcfConstant.MESSAGE_LOGIN_ACCOUNT_OR_PWD_EMPTY);
            return "member_login";
        }
        // 在数据库中通过账号查询目标
        ResultEntity<MemberPO> memberByUsername = mysqlRemoteService.getMemberByUsername(loginacct);
        if (ResultEntity.getFAILURE().equals(memberByUsername.getResult())) {
            modelMap.addAttribute(NhcfConstant.ATTR_MESSAGE_NAME, memberByUsername.getMsg());
            return "member_login";
        }
        // 判断用户是否存在
        MemberPO memberPO = memberByUsername.getData();
        if (memberPO == null) {
            modelMap.addAttribute(NhcfConstant.ATTR_MESSAGE_NAME, NhcfConstant.MESSAGE_LOGIN_ACCOUT_NOT_EXISTS);
            return "member_login";
        }
        // 判断账号或密码是否存在正确
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String passwordInDao = memberPO.getUserpswd();
        if (!bCryptPasswordEncoder.matches(userpswd, passwordInDao)) {
            modelMap.addAttribute(NhcfConstant.ATTR_MESSAGE_NAME, NhcfConstant.MESSAGE_LOGIN_FAILUIRE);
            return "member_login";
        }
        // 将登录状态保存到Session中
        Integer id = memberPO.getId();
        String username = memberPO.getLoginacct();
        String name = memberPO.getUsername();
        String email = memberPO.getEmail();
        MemberLoginVO memberLoginVO = new MemberLoginVO(id, username, name, email);
        session.setAttribute(NhcfConstant.ATTR_NAME_MEMBER, memberLoginVO);

        return "redirect:/member/auth/to/home/page";
    }

    @RequestMapping("member/auth/do/submit")
    public String doSubmit(MemberVO memberVO, ModelMap modelMap) {
        // 判断两次输入的密码是否相同
        String userpswd = memberVO.getUserpswd();
        String dupps = memberVO.getDupps();
        if (!userpswd.equals(dupps)) {
            modelMap.addAttribute(NhcfConstant.ATTR_MESSAGE_NAME, NhcfConstant.MESSAGE_REGISTER_TWICE_PSW_NOT_MATCH);
            return "member_register";
        }
        // 拼接Redis key
        String phoneNum = memberVO.getPhoneNum();
        String key = NhcfConstant.REDIS_CODE_PREFIX + phoneNum;
        ResultEntity<String> res = redisRemoteService.getRedisStringValueByKeyRemote(key);
        if (ResultEntity.getSUCCESS().equals(res.getResult())) {
            String codeInRedis = res.getData();
            String code = memberVO.getCode();
            if  (codeInRedis == null) {
                modelMap.addAttribute(NhcfConstant.ATTR_MESSAGE_NAME, NhcfConstant.MESSAGE_CODE_NOT_EXISTS);
                return "member_register";
            }
            if (code.equals(codeInRedis)) {
                // 移除redis中的验证码
                redisRemoteService.removeRedisKeyRemote(key);
                // 密码加密
                BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
                String encodedPsw = bCryptPasswordEncoder.encode(userpswd);
                memberVO.setUserpswd(encodedPsw);
                // 用户信息持久化
                MemberPO memberPO = new MemberPO();
                BeanUtils.copyProperties(memberVO, memberPO);
                ResultEntity resultEntity = mysqlRemoteService.saveMemberRemote(memberPO);
                if (ResultEntity.getFAILURE().equals(resultEntity.getResult())) {
                    modelMap.addAttribute(NhcfConstant.ATTR_MESSAGE_NAME, NhcfConstant.MESSAGE_LOGIN_ACCOUT_ALREADY_EXISTED);
                    return "member_register";
                }
            } else {
                modelMap.addAttribute(NhcfConstant.ATTR_MESSAGE_NAME, NhcfConstant.MESSAGE_CODE_WRONG);
                return "member_register";
            }
        } else {
            modelMap.addAttribute(NhcfConstant.ATTR_MESSAGE_NAME, res.getMsg());
            return "member_register";
        }

        return "member_login";
    }

    @RequestMapping("member/auth/send/sms/page")
    @ResponseBody
    public ResultEntity sendSms(@RequestParam("phoneNum") String phoneNum) {
        // 发送短信
        ResultEntity resultEntity = SendSmsUtil.sendSms(shortMessageProperties.getCodeCount(), shortMessageProperties.getAppcode(), phoneNum,
                shortMessageProperties.getSmsSignId(), shortMessageProperties.getTemplateId());
        if (ResultEntity.getSUCCESS().equals(resultEntity.getResult())) {
            String key = NhcfConstant.REDIS_CODE_PREFIX + phoneNum;
            String code = resultEntity.getData().toString();
            ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 10, TimeUnit.MINUTES);
            if (ResultEntity.getSUCCESS().equals(saveCodeResultEntity.getResult())) {
                return ResultEntity.successWithoutData();
            } else {
                return saveCodeResultEntity;
            }
        } else {
            return ResultEntity.failureWithMsg(resultEntity.getMsg());
        }
    }
}
